import json
import logging
from common_tools import get_app_log_handler
from common_tools import decrypt

from flask_bcrypt import Bcrypt
from flask_httpauth import HTTPBasicAuth
from flask_sqlalchemy import SQLAlchemy
from flask_limiter import Limiter

# 基础路径
base_path = "."

# 项目名称
PROJECT_NAME = "python-vue-admin"

# 项目密钥
SECRET_KEY = "1qazxsw23edcvfr45tgbnhy6"
algorithm = "chacha20"
WeChatAppId = "YCNQw1FPYqCgbQMlJ4nUpA==:nRutx4rN9EHyLBUtUgKomFWu"
WechatSecretKey = "u9TxfXqQEINFcVyc9VIpIA==:t7heUhDAYv4e/rLMEv/XSRhP6o3UnDnyv6qjJ878WWQ="

WeChatAlreadyPrepared = False
WeChatAccessTokenExpireSeconds = 7000
IMAGE_BED_TOKEN = "9955e6fa91a2426ba82d6f4cc7807ebe"
IMAGE_UPLOAD_URL = "https://api.superbed.cn/upload"
BCRYPT_HASH_PREFIX = "2b"
BCRYPT_HANDLE_LONG_PASSWORDS = False
MAX_PAGE_SIZE = 3000
# 令牌过期时间
TOKEN_EXPIRE = 24 * 7  # 一周
UPLOAD_FOLDER = 'uploads'  # 文件上传路径
MAX_CONTENT_LENGTH = 1024 * 1024 * 16  # 限制文件大小为 16 MB
DOWNLOAD_FOLDER = "downloads"
IMAGE_SEP = " "
TAG_SEP = "|"
IP_SEP = "|"
# 数据库配置
DB_CONFIG = {
    'user': 'wangchenxi',
    'password': '1hblsqt!',  # 请替换为实际密码
    'host': '172.30.86.160',
    'database': 'vna',
    'raise_on_warnings': True
}

contacts_sheet_name = "联系人"
field_stacks_sheet_name = "堆场管理"
areas_sheet_name = '堆区管理'
box_tags_sheet_name = '箱柜标签'
box_types_sheet_name = '箱柜类型'
boxs_sheet_name = "箱柜管理"
images_sheet_name = "项目图片"
configuration_sheet_name = "配置管理"
leads_sheet_name = "线索管理"
ips_sheet_name = "IP信息"

configurations_file = "configurations.json"

configurations = dict()

WeChatAccessToken = ""


def set_wechat_access_token(token: str):
    """
    设置微信访问令牌。
    :param token: 微信访问令牌
    :return: None
    """
    global WeChatAccessToken
    WeChatAccessToken = token


def get_wechat_access_token() -> str:
    """
    获取微信访问令牌。
    :return: 微信访问令牌
    """
    global WeChatAccessToken
    if not WeChatAccessToken:
        raise Exception("WeChatAccessToken is not set.")
    else:
        return WeChatAccessToken


def get_32_bytes_from_secret_key() -> bytes:
    """
    获取32字节的密钥。
    :param secret: 密钥
    :return: 32字节密钥
    """
    if SECRET_KEY:
        secret_key = SECRET_KEY * 32
        secret_key = secret_key[:32]
        return secret_key.encode()
    else:
        raise Exception("SECRET_KEY is not set.")


def get_wechat_appid() -> str:
    """
    获取微信小程序ID。
    :return: 微信小程序ID
    """
    if not WeChatAppId:
        raise Exception("WeChatAppId is not set.")
    else:
        return decrypt(algorithm, get_32_bytes_from_secret_key(), WeChatAppId)


def get_wechat_secret() -> str:
    """
    获取微信小程序密钥。
    :return: 微信小程序密钥
    """
    if not WechatSecretKey:
        raise Exception("WechatSecretKey is not set.")
    else:
        return decrypt(algorithm, get_32_bytes_from_secret_key(), WechatSecretKey)


def get_init_configuration(key: str) -> str:
    """
    获取配置文件。
    :param key: 配置文件key
    :return: 配置文件
    """
    global configurations
    if not configurations:
        with open(configurations_file, 'r', encoding='utf-8') as f:
            configurations = json.load(f)
    return configurations[key]


def get_init_configurations() -> dict:
    """
    获取配置文件。
    :return: 配置文件
    """
    global configurations
    if not configurations:
        with open(configurations_file, 'r', encoding='utf-8') as f:
            configurations = json.load(f)
    return configurations


# 日志记录器
LOGGER = get_app_log_handler(PROJECT_NAME, base_path=base_path, logger_level=logging.DEBUG)
TRACE_LOGGER = get_app_log_handler(f"trace.{PROJECT_NAME}", base_path=base_path, logger_level=logging.DEBUG)
SCHEDULER_LOGGER = get_app_log_handler(f"scheduler.{PROJECT_NAME}", base_path=base_path, logger_level=logging.DEBUG)


def get_db_url_info(user: str, password: str, host: str, database: str, **kwargs) -> str:
    """
    生成数据库连接URL。

    :param user: 数据库用户名
    :param password: 数据库密码
    :param host: 数据库主机
    :param database: 数据库名称
    :return: 数据库连接URL
    """
    #  这个参数暂时没有使用，后续如果需要可以加上
    if kwargs.get('raise_on_warnings', True):
        kwargs['raise_on_warnings'] = True
    return f'mysql+pymysql://{user}:{password}@{host}/{database}'


DB_INFO = get_db_url_info(**DB_CONFIG)

# 加密工具
bcrypt = Bcrypt()
auth = HTTPBasicAuth()


def set_bcrypt(obj: Bcrypt):
    """
    设置全局Bcrypt实例。

    :param obj: Bcrypt实例
    """
    global bcrypt
    bcrypt = obj


def get_bcrypt() -> Bcrypt:
    """
    获取全局Bcrypt实例。

    :return: Bcrypt实例
    """
    global bcrypt
    return bcrypt


def get_auth() -> HTTPBasicAuth:
    """
    获取全局HTTPBasicAuth实例。

    :return: HTTPBasicAuth实例
    """
    global auth
    return auth


def set_auth(obj: HTTPBasicAuth):
    """
    设置全局HTTPBasicAuth实例。

    :param obj: HTTPBasicAuth实例
    """
    global auth
    auth = obj


# 数据库实例
db: SQLAlchemy = SQLAlchemy()


def set_db(obj: SQLAlchemy):
    """
    设置全局SQLAlchemy实例。

    :param obj: SQLAlchemy实例
    """
    global db
    db = obj


def get_db() -> SQLAlchemy:
    """
    获取全局SQLAlchemy实例。

    :rtype: object
    :return: SQLAlchemy实例
    """
    global db
    return db


# 流控实例
limiter: Limiter


def get_limiter() -> Limiter:
    """
    获取全局Limiter实例。
    :rtype: object
    :return: Limiter实例
    """
    global limiter
    if not limiter:
        raise Exception("limiter is not set.")
    else:
        return limiter


def set_limiter(obj: Limiter):
    """
    设置全局Limiter实例。
    :param obj: Limiter实例
    """
    global limiter
    limiter = obj
